﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
/**
 * Parancs értelmezést végző névtér...
 * TODO:
 * - Parancsfüggvények meghívása readElement()
 * - Kamerás függvények alkalmazása: addElement()
 * - "Játéktér" meghatározás - mely szín, hol milyen parancsot hívjon?
 * - Többszálasítás kell-e??
 */
namespace ConsoleApplication1
{
    /**
     * Színek elmozduláslnak a követése
     */ 
    class Commander
    {
        int buffSize = 10;
        int comboBufferSize = 1;
        public int[] comboBuffer;
        public int[] colors; // colors to track
        int cSize;   // number of colors
        Element[] position;
        public Queue commands;
        /*
         * Egy utasítás egy 2 helyiértékű int lesz. 
         * 10-es helyiérték a szín -> 10 szín max
         * 1-es helyiérték az irány (1-fel,2-le,3-jobb,4-bal)
         * pl: 11, 12, 11, 14, 31 ...
         */
        public Commander(int cSize)
            : this(cSize, 1)
        {
        }
        public Commander(int cSize, int comboBufferSize)
        {
            this.comboBufferSize = comboBufferSize;
            if (cSize > 10)
                this.cSize = 10;
            else
                this.cSize = cSize;
            colors = new int[cSize];
            position = new Element[cSize];
            for (int i = 0; i < this.cSize; i++)
            {
                position[i] = new Element(-1,-1);
            }
            this.commands = new Queue();
            this.comboBuffer = new int[this.comboBufferSize];
        }
        public Commander(int cSize, int buffSize, int comboBufferSize)
            : this(cSize, comboBufferSize)
        {
            this.buffSize = buffSize;
        }
        /**
         * Függvény a megadott szín "megjegyzésére".
         */ 
        public bool setColor(int cNum, int color)
        {
            if (this.cSize < cNum || cNum < 0)
            {
                return false;
            }
            else
            {
                this.colors[cNum] = color;
                return true;
            }
        }
        public void dequeueCommands()
        {
            if (this.commands.Count >= this.comboBufferSize)
            {
                for (int i = 0; i < this.comboBufferSize; i++)
                {
                    this.comboBuffer[i] = 0;
                }
                for (int i = 0; i < this.comboBufferSize; i++)
                {
                    this.comboBuffer[i] = (int) this.commands.Dequeue();
                }
                /**
                 * Itt meg kell vizsgálni a combó buffer teljes tartalmát.
                 * Most nekünk csak 1 értéket tartalmaz, ezért csak 1 feltételt kell nézni...
                 */ 
                if(this.comboBuffer[0] == 11)
                {
                    Console.Write("Up! ");
                }
                if (this.comboBuffer[0] == 12)
                {
                    Console.Write("Down! ");
                }
                if (this.comboBuffer[0] == 13)
                {
                    Console.Write("Right! ");
                }
                if (this.comboBuffer[0] == 14)
                {
                    Console.Write("Left! ");
                }
                Console.WriteLine();
            }
        }
        public void enqueueDirection(int x, int y, int c)
        {
            for (int i=0 ; i<this.comboBufferSize ; i++)
            {
                if (c == colors[i])
                {
                    if (position[i].x == -1 && position[i].y == -1)
                    {
                        position[i].x = x;
                        position[i].y = y;
                    }
                    else
                    {
                        // hosszak az egyes dimenziókban - vetületek/befogók
                        int tempX = position[i].x - x;
                        int tempY = position[i].y - y;
                        // hossz meghatározása
                        int length = (int)Math.Sqrt((tempX * tempX + tempY * tempY));
                        // Ha a hossz nagyobb mint egy buffer érték, csak akkor csapunk!
                        if (length > buffSize)
                        {
                            // abszolútértéket ki kell számolni, sajnos...
                            int absTempX, absTempY;
                            if (tempX < 0) absTempX = (-1) * tempX;
                            else absTempX = tempX;
                            if (tempY < 0) absTempY = (-1) * tempY;
                            else absTempY = tempY;
                            if (absTempX < absTempY)
                            {
                                if (tempX < 0)
                                {
                                    commands.Enqueue(c*10+2);
                                    Console.WriteLine("Down!");
                                }
                                else
                                {
                                    commands.Enqueue(c * 10 + 1);
                                    Console.WriteLine("Up!");
                                }
                            }
                            else
                            {
                                if (tempY < 0)
                                {
                                    commands.Enqueue(c * 10 + 4);
                                    Console.WriteLine("Left!");
                                }
                                else
                                {
                                    commands.Enqueue(c * 10 + 3);
                                    Console.WriteLine("Right!");
                                }
                            }
                            position[i].x = x;
                            position[i].y = y;
                        }
                        else
                        {
                            Console.WriteLine("Nothing!");
                        }
                    }
                }
            }
        }
    }
    class Element
    {
        public int x;
        public int y;
        public Element(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }






    class Program
    {
        static void Main(string[] args)
        {
            Commander p = new Commander(1);
            p.setColor(0, 1);
            Console.WriteLine(p.colors[0]);


            while (true)
            {
                p.enqueueDirection(20, 30, 1);
                Console.WriteLine("X");
                p.enqueueDirection(200, 300, 1);
                Console.WriteLine("X");
                p.enqueueDirection(200, 300, 1);
                Console.WriteLine("X");
                p.enqueueDirection(210, 310, 1);
                Console.WriteLine("X");
                p.enqueueDirection(20, 30, 1);

                Console.WriteLine("OUT:");
                if (p.commands.Count>1)
                {
                    p.dequeueCommands();
                }
            }
            //// Teszt...
            //Program p = new Program();
            //Console.WriteLine(p.addElement(10,30,1));
            //Console.WriteLine(p.addElement(3, 60, 1));
            //Console.WriteLine(p.addElement(200, 400, 1));
            //Console.WriteLine(p.queuePosition);
            //for (int i = 0; i < p.queuePosition; i++)
            //{
            //    p.readElement();
            //    //QueueElement temp = p.Test.Dequeue();
            //    //Console.WriteLine(temp.x + " " + temp.y);
            //    //Console.WriteLine(p.queue[i].x + " " + p.queue[i].y);
            //}
            Console.ReadLine();
        }
    }
}
